package com.java.ch032;

import java.text.DecimalFormat;

public class Matrix {
    private double[][] data; //矩阵数据

    public Matrix() {
    }//默认构造函数

    public Matrix(double[][] data) { //默认构造函数
        if (CanTransToMatrix(data)) //判断数组是否能转换为矩阵
            this.data = this.cloneArray(data);
    }

    //判断数组是否能转换为矩阵
    private static boolean CanTransToMatrix(double[][] data) {
        if (data == null) return false; //判断二维数组是否为空
        for (int i = 0; i <= data.length - 2; i++) {
            if (data[i].length != data[i + 1].length) return false;
            return false;
        }
        return true;
    }

    public String showArray(double[][] data) {
        DecimalFormat format = new DecimalFormat("0.00");
        StringBuffer buffer = new StringBuffer(" ");
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data.length; j++) {
                // 将数组元素转换为指定格式
                buffer.append(format.format(data[i][j])).append(" ");
            }
            buffer.append("\n");
        }
        return buffer.toString();
    }

    //调用方法显示二维数组
    public void showData() {
        System.out.println(showArray(this.data));
    }

    // 克隆一个二维数组
    private double[][] cloneArray(double[][] data) {
        if (data == null) return null;
        return (double[][]) data.clone();
    }

    //获得矩阵
    public double[][] getMatrixData() {
        return cloneArray(this.data);
    }

    //矩阵加法运算
    public Matrix add(Matrix t) {
        if (t == null) return null;
        Matrix text = null;
        double[][] tmData = t.getMatrixData(); //获得一个矩阵
        if ((this.data.length != tmData.length) || (this.data[0].length != tmData[0].length)) {
            System.out.println("两个矩阵大小不一");
            return text;
        } else {
            double[][] result = new double[this.data.length][this.data[0].length];
            for (int i = 0; i < this.data.length; i++) {
                for (int j = 0; j < this.data[0].length; j++) {
                    result[i][j] = this.data[i][j] + tmData[i][j];
                }
            }
            text = new Matrix(result); //将新生成的矩阵传入对象中
            return text; //返回对象
        }
    }

    // 矩阵减法运算
    public Matrix subtration(Matrix t) {
        if (t == null) return null;
        Matrix text = null;
        double[][] tmData = t.getMatrixData(); // 获取一个矩阵
        if ((this.data.length != tmData.length) || (this.data[0].length != tmData[0].length)) {
            System.out.println("两个矩阵大小不一");
            return text;
        } else {
            double[][] result = new double[this.data.length][this.data[0].length];
            for (int i = 0; i < this.data.length; i++) { //依次循环的行数
                for (int j = 0; j < this.data[0].length; j++) {
                    result[i][j] = this.data[i][j] - tmData[i][j];
                }
            }
            text = new Matrix(result);
            return text;
        }
    }

    // 矩阵转置
    public Matrix transposeMatrix() {
        int Row = this.data[0].length;
        int Column = this.data.length;
        double[][] change = new double[Row][Column];
        for (int i = 0; i < Row; i++) {
            for (int j = 0; j < Column; j++) {
                change[i][j] = this.data[i][j];
            }
        }
        return new Matrix(change);
    }

    public static void main(String[] args) {
        // 构造一个二维数组
        double[][] data1 = new double[][]{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}};
        //声明一个空的二维数组
        double[][] data2 = new double[3][3];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                data2[i][j] = 2 * i + j;
            }
        }
        Matrix matrix1 = new Matrix(data1);
        Matrix matrix2 = new Matrix(data2);
        System.out.println("两组二维数组展示：");
        matrix1.showData();
        matrix2.showData();
        System.out.println("矩阵加法运算结果：");
        matrix1.add(matrix2).showData();
        System.out.println("矩阵减法运算结果: ");
        matrix1.subtration(matrix2).showData();
        System.out.println("矩阵matrix1转置结果:");
        matrix1.transposeMatrix().showData();
    }
}